from django.views import View
from django.http import JsonResponse
import json
import logging
import re
from django.conf import settings
from django.contrib.auth import login, logout, authenticate
from django.utils.decorators import method_decorator
from django.views import View
from django import http
from django_redis import get_redis_connection
from pymysql import DatabaseError
import imghdr  # 文件检查

from libs.qiniuyun.qiniu_storage import storage


class RegisterView(View):
    """用户注册"""

    def post(self, request):
        # 接受前段穿的json数据
        json_data = request.body.decode()
        # 将json转化为字典数据
        dict_data = json.loads(json_data)
        mobile = dict_data.get("mobile")
        phonecode = dict_data.get("phonecode")
        password = dict_data.get("password")
        # 验证字段数据all方法红如果有空值会返回false
        if not all([mobile, phonecode, password]):
            return JsonResponse({'code': 400, 'errmsg': '缺少必传参数!'})
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return JsonResponse({'code': 400, 'errmsg': 'mobile格式有误!'})
        # 判断密码格式
        if not re.match(r'^[a-zA-Z0-9]{8,20}$', password):
            return JsonResponse({'code': 400, 'errmsg': 'password格式有误!'})

        # # 校验用户输入的手机验证码和redis保存的手机验证码是否一致
        redis_conn = get_redis_connection("verify")
        # sms_code = redis_conn.get('sms_%s' % mobile)
        sms_code = phonecode
        # # 判断real_code是否超过有效期
        if not sms_code:
            return JsonResponse({'code': 400, 'errmsg': '验证码失效'}, status=400)
        # 判断输入的验证码和ｒｅｄｉｓ中的是否一致
        if sms_code != phonecode:
            return JsonResponse({'code': 400, 'errmsg': '验证码不一致'})
        # 将数据堡村子啊数据库中create()保存数据不会对用户密码加密

        # 三、业务逻辑
        save_data = {
            "username": mobile,
            "mobile": mobile,
            "password": password
        }
        user = User.objects.create_user(**save_data)
        # try:
        #     user = User.objects.create_user(**save_data)
        # except DatabaseError as e:
        #     logger.error(e)
        # return JsonResponse({"errno": 0, "errmsg": "注册成功"})

        # create_user（）会对用户密码进行加密
        # User.objects.create()
        # user = User.objects.create_user(
        #                          password=password,mobile=mobile)
        # 用户注册成功，需要进行状态保持,第一个参数request对象,第二个参数是用户对象
        login(request, user)
        # 返回结果

        return JsonResponse({"errno": "0", "errmsg": "注册成功"})


class LoginView(View):
    """
    需求：登录实现
    """

    def get(self, request):

        # 1、判断用户是否登录，需要获取user
        user = request.user
        # 2、对user进行认证
        if not user.is_authenticated:
            return JsonResponse({"errno": "0", "errmsg": "用户未登录"})

        data = {
            "user_id": user.id,
            "name": user.username
        }

        return JsonResponse({"errno": "0", "errmsg": "已登录", "data": data})

    def post(self, request):
        # user = request.user
        dict_data = json.loads(request.body.decode())
        mobile = dict_data.get('mobile')
        password = dict_data.get('password')

        # 校验参数
        # 判断参数是否齐全
        if not all([mobile, password]):
            return JsonResponse({"errno": "0", "errmsg": "参数不全"})

        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return JsonResponse({"errno": "0", "errmsg": "请输入正确的手机号码"})

        # 认证登录用户
        user = authenticate(username=mobile, password=password)
        if user is None:
            return JsonResponse({"errno": "0", "errmsg": "请输入正确的手机号码"})

        # 实现状态保持
        login(request, user)

        return JsonResponse({"errno": "0", "errmsg": "登录成功"})

    def delete(self, request):
        # 退出登录
        logout(request)

        return JsonResponse({"errno": "0", "errmsg": "退出成功"})


# todo：这里等待外部链接


from apps.users.models import User

logger = logging.getLogger('django')


def image_file(value):
    # 检查是否是图片文件
    try:
        file_type = imghdr.what(value)
        return file_type if file_type else None
    except:
        return None


def login_required(view_func):
    # 用户登录装饰器，检查是否登录
    def wrapper(request, *args, **kwargs):
        if request.user.is_authenticated:
            return view_func(request, *args, **kwargs)
        else:
            return http.JsonResponse({"errno": 404, "errmsg": "用户未登录"})

    return wrapper


class UserInfoView(View):
    # 用户中心
    @method_decorator(login_required)
    # 给视图函数添加登录装饰器
    def get(self, request):
        # 1、获取数据
        user = request.user
        return http.JsonResponse({"errno": 0, "errmsg": "OK", "data": user.to_basic_dict()})


class AvatarView(View):
    # 上传头像
    @method_decorator(login_required)
    def post(self, request):
        # 1、接收参数
        avatar = request.FILES.get("avatar")
        if not avatar:
            return http.JsonResponse({"errno": 404, "errmsg": "参数错误"})
        if not image_file(avatar):
            return http.JsonResponse({"errno": 404, "errmsg": "参数错误"})
        # 读取出文件对象的二进制数据
        file_data = avatar.read()
        try:
            key = storage(file_data)
        except Exception as e:
            logger.error(e)
            return http.JsonResponse({"errno": 404, "errmsg": "上传图片失败"})
        try:
            request.user.avatar = key
            request.user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": 404, "errmsg": "图片保存失败"})
        data = {
            "avatar_url": settings.QINIU_URL + key
        }
        return http.JsonResponse({"errno": 0, "errmsg": "OK", "data": data})


class ModifyNameView(View):
    # 修改用户名
    @method_decorator(login_required)
    def put(self, request):
        dict_data = json.loads(request.body.decode())
        username = dict_data.get("name")

        user = request.user
        try:
            user.username = username
            user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": 404, "errmsg": "数据保存失败"})
        return http.JsonResponse({"errno": 0, "errmsg": "修改成功"})


class UserAuthView(View):
    # 用户实名认证
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(UserAuthView, self).dispatch(*args, **kwargs)

    def get(self, request):
        # 显示认证信息
        data = request.user.to_auth_dict()
        return http.JsonResponse({"errno": 0, "errmsg": '认证信息查询成功', "data": data})

    def post(self, request):
        # 保存用户认证信息，数据库中添加字段
        dict_data = json.loads(request.body.decode())
        real_name = dict_data.get("real_name")
        id_card = dict_data.get("id_card")
        if not all([real_name, id_card]):
            return http.JsonResponse({"errno": 404, "errmsg": "参数错误"})
        user = request.user
        try:
            user.real_name = real_name
            user.id_card = id_card
            user.save()
        except DatabaseError as e:
            logger.error(e)
            return http.JsonResponse({"errno": 404, "errmsg": "数据保存失败"})
        else:
            return http.JsonResponse({"errno": 0, "errmsg": '认证信息保存成功'})
